﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

using log4net;

using Azure.Resources;

namespace Azure.Logger
{
    public static class AzLogger
    {
        private static ILog s_generalLogger = null;
        private static ILog s_stackLogger = null;

        //线程ID与时间的字典
        private static Dictionary<int, DateTime> s_performMap = null;
        private static Dictionary<int, String> s_performTaskNameMap = null;

        static AzLogger()
        {
            log4net.Config.XmlConfigurator.Configure(AzEmbeddedResourcesManager.GetLog4netConfigResrouce());

            s_generalLogger = LogManager.GetLogger("GeneralLogger");
            s_stackLogger = LogManager.GetLogger("ExceptionStackLogger");

            s_performMap = new Dictionary<int, DateTime>();
            s_performTaskNameMap = new Dictionary<int, string>();
        }

        public static void EnterFunction(String funName)
        {
            s_generalLogger.Debug("Enter function: " + funName);
        }

        public static void LeaveFunction(String funName)
        {
            s_generalLogger.Debug("Leave function: " + funName);
        }

        public static void Error(String message)
        {
            s_generalLogger.Error(message);
        }

        public static void Error(Exception ex)
        {
            s_generalLogger.Error(ex.Message);
            s_stackLogger.Error("", ex);
        }

        public static void Error(String message, Exception ex)
        {
            s_generalLogger.Error(message + "|" + ex.Message);
            s_stackLogger.Error("", ex);
        }

        public static void Warn(String message)
        {
            s_generalLogger.Warn(message);
        }

        public static void Warn(Exception ex)
        {
            s_generalLogger.Warn(ex.Message);
            s_stackLogger.Warn("", ex);
        }

        public static void Warn(String message, Exception ex)
        {
            s_generalLogger.Warn(message + "|" + ex.Message);
            s_stackLogger.Warn("", ex);
        }

        public static void Info(String message)
        {
            s_generalLogger.Info(message);
        }

        public static void Important(String message)
        {
            s_generalLogger.Info("[Important] " + message);
        }

        public static void PerfStart(String taskName)
        {
            DateTime now = DateTime.Now;
            s_generalLogger.Info("[Performance] [task name = " + taskName + "] [Enter Time] " + now.ToString());

            //加到字典中去，如果同一线程下次调用EnePerf时就能知道2次调用之间的差
            lock (s_performMap)
            {
                s_performMap[Thread.CurrentThread.ManagedThreadId] = now;
                s_performTaskNameMap[Thread.CurrentThread.ManagedThreadId] = taskName;
            }
        }

        public static void PerfEnd()
        {
            DateTime now = DateTime.Now;

            if (!s_performMap.ContainsKey(Thread.CurrentThread.ManagedThreadId))
            {
                s_generalLogger.Info("[Performance] 没有找到对应的PerfStart");
            }
            else
            {
                DateTime startTime = s_performMap[Thread.CurrentThread.ManagedThreadId];
                String taskName = s_performTaskNameMap[Thread.CurrentThread.ManagedThreadId];

                s_generalLogger.Info("[Performance] [task name = " + taskName + "] [Exit Time] " + now.ToString() + " [Time Span] " + (now - startTime).ToString());

                lock (s_performMap)
                {
                    s_performMap.Remove(Thread.CurrentThread.ManagedThreadId);
                    s_performTaskNameMap.Remove(Thread.CurrentThread.ManagedThreadId);
                }
            }
        }
    }
}
